package com.codedancer.campus.client.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.codedancer.campus.client.service.ICommodityService;
import com.codedancer.campus.client.service.bo.commodity.CommodityAddOrUpdateBo;
import com.codedancer.campus.client.service.bo.commodity.CommodityPageSearchBo;
import com.codedancer.campus.client.service.vo.commodity.CommodityVo;
import com.codedancer.campus.common.dataresource.ExternalApiData;
import com.codedancer.campus.common.exception.BusinessException;
import com.codedancer.campus.common.utils.UUIDGenerator;
import com.codedancer.campus.enums.CommodityStatus;
import com.codedancer.campus.mapper.CategoryMapper;
import com.codedancer.campus.mapper.CommodityCollectionMapper;
import com.codedancer.campus.mapper.CommodityImageMapper;
import com.codedancer.campus.mapper.CommodityMapper;
import com.codedancer.campus.mapper.SchoolMapper;
import com.codedancer.campus.mapper.UserMapper;
import com.codedancer.campus.mapper.UserSchoolMapper;
import com.codedancer.campus.po.Category;
import com.codedancer.campus.po.Commodity;
import com.codedancer.campus.po.CommodityCollection;
import com.codedancer.campus.po.CommodityImage;
import com.codedancer.campus.po.School;
import com.codedancer.campus.po.User;
import com.codedancer.campus.po.UserSchool;
import com.codedancer.campus.qo.commodity.CommodityPageSearchQo;

import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional(rollbackFor = Exception.class)
public class CommodityServiceImpl implements ICommodityService {

    @Autowired
    private CommodityMapper commodityMapper;
    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private CommodityImageMapper commodityImageMapper;
    @Autowired
    private UserSchoolMapper userSchoolMapper;
    @Autowired
    private SchoolMapper schoolMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private CommodityCollectionMapper commodityCollectionMapper;
    @Autowired
    private ExternalApiData externalApiData;

    /**
     * 发布商品
     *
     * @param commodityAddOrUpdateBo 发布商品Bo
     */
    @Override
    public void publish(CommodityAddOrUpdateBo commodityAddOrUpdateBo) {
        Category category = categoryMapper.findById(commodityAddOrUpdateBo.getCategoryUuid())
            .orElseThrow(() -> new BusinessException("分类不存在"));
        if (CollUtil.isEmpty(commodityAddOrUpdateBo.getImageUrls())) {
            throw new BusinessException("请上传图片");
        }
        if (externalApiData.checkSensitiveWords(commodityAddOrUpdateBo.getTitle()) || externalApiData.checkSensitiveWords(commodityAddOrUpdateBo.getDescription())) {
            throw new BusinessException("商品标题或描述存在敏感词");
        }
        Commodity commodity = BeanUtil.copyProperties(commodityAddOrUpdateBo, Commodity.class);
        commodity.setUuid(UUIDGenerator.getUUID());
        commodity.setPublishUserUuid(commodityAddOrUpdateBo.getCurrentUserUuid());
        commodity.setPlateUuid(category.getPlateUuid());
        // 设置为待审核
        commodity.setStatus(CommodityStatus.PENDING_REVIEW);
        // 查询用户所属学校uuid
        UserSchool userSchool = userSchoolMapper.findByColumn("user_uuid",
                commodityAddOrUpdateBo.getCurrentUserUuid())
            .orElseThrow(() -> new BusinessException("所属学校不存在，不能发布"));
        commodity.setPublishSchoolUuid(userSchool.getSchoolUuid());
        commodityMapper.insert(commodity);
        // 保存商品图片信息
        for (String imageUrl : commodityAddOrUpdateBo.getImageUrls()) {
            CommodityImage commodityImage = CommodityImage.builder()
                .imageUrl(imageUrl).commodityUuid(commodity.getUuid())
                .uuid(UUIDGenerator.getUUID()).build();
            commodityImageMapper.insert(commodityImage);
        }
    }

    /**
     * 分页获取用户发布商品
     *
     * @param commodityPageSearchBo
     * @return
     */
    @Override
    public IPage<CommodityVo> pageSearchUserCommodity(CommodityPageSearchBo commodityPageSearchBo) {
        CommodityPageSearchQo commodityPageSearchQo = BeanUtil.copyProperties(commodityPageSearchBo,
            CommodityPageSearchQo.class);
        IPage<Commodity> commodityIPage = commodityMapper.pageSearchUserCommodity(
            new Page<>(commodityPageSearchBo.getPage(), commodityPageSearchBo.getSize()),
            commodityPageSearchQo);
        IPage<CommodityVo> commodityVoIPage = new Page<>();
        List<CommodityVo> commodityVos;
        commodityVos = commodityIPage.getRecords().stream().map(commodity -> {
            CommodityVo commodityVo = BeanUtil.copyProperties(commodity, CommodityVo.class);
            // 获取分类
            Category category = categoryMapper.findById(commodity.getCategoryUuid())
                .orElseThrow(() -> new BusinessException("分类不存在"));
            commodityVo.setCategoryName(category
                .getName());
            // 获取该商品图片
            List<CommodityImage> commodityImages = commodityImageMapper.selectListByColumn(
                "commodity_uuid", commodity.getUuid());
            commodityVo.setFirstImage(commodityImages.get(0).getImageUrl());
            // 获取发布学校
            School school = schoolMapper.findById(commodity.getPublishSchoolUuid())
                .orElseThrow(() -> new BusinessException("发布学校不存在"));
            commodityVo.setPublishSchoolName(school.getName());
            return commodityVo;
        }).collect(Collectors.toList());
        commodityVoIPage.setTotal(commodityIPage.getTotal());
        commodityVoIPage.setRecords(commodityVos);
        return commodityVoIPage;
    }

    /**
     * 分页查询商品
     *
     * @param commodityPageSearchBo
     * @return
     */
    @Override
    public IPage<CommodityVo> pageSearch(CommodityPageSearchBo commodityPageSearchBo) {
        UserSchool userSchool = userSchoolMapper.selectOneByColumn("user_uuid",
            commodityPageSearchBo.getCurrentUserUuid());
        CommodityPageSearchQo commodityPageSearchQo = BeanUtil.copyProperties(commodityPageSearchBo,
            CommodityPageSearchQo.class);
        commodityPageSearchQo.setPublishSchoolUuid(userSchool.getSchoolUuid());
        IPage<Commodity> commodityIPage = commodityMapper.pageSearch(
            new Page<>(commodityPageSearchBo.getPage(), commodityPageSearchBo.getSize()),
            commodityPageSearchQo);
        IPage<CommodityVo> commodityVoIPage = new Page<>();
        List<CommodityVo> commodityVos;
        commodityVos = commodityIPage.getRecords().stream().map(commodity -> {
            CommodityVo commodityVo = BeanUtil.copyProperties(commodity, CommodityVo.class);
            // 获取分类
            Category category = categoryMapper.findById(commodity.getCategoryUuid())
                .orElseThrow(() -> new BusinessException("分类不存在"));
            commodityVo.setCategoryName(category
                .getName());
            User user = userMapper.selectById(commodity.getPublishUserUuid());
            commodityVo.setPublishUserName(user.getNickName());
            // 获取该商品图片
            List<CommodityImage> commodityImages = commodityImageMapper.selectListByColumn(
                "commodity_uuid", commodity.getUuid());
            commodityVo.setFirstImage(commodityImages.get(0).getImageUrl());
            return commodityVo;
        }).collect(Collectors.toList());
        commodityVoIPage.setTotal(commodityIPage.getTotal());
        commodityVoIPage.setRecords(commodityVos);
        return commodityVoIPage;
    }

    /**
     * 商品详情
     *
     * @param commodityUuid
     * @return
     */
    @Override
    public CommodityVo detail(String commodityUuid) {
        Commodity commodity = commodityMapper.findById(commodityUuid)
            .orElseThrow(() -> new BusinessException("商品不存在"));
        if (commodity.getStatus().equals(CommodityStatus.OFF_SHELF)) {
            throw new BusinessException("该商品已下架");
        }
        CommodityVo commodityVo = BeanUtil.copyProperties(commodity, CommodityVo.class);
        Category category = categoryMapper.selectById(commodity.getCategoryUuid());
        commodityVo.setCategoryName(category.getName());
        commodityVo.setCategoryUuid(category.getUuid());
        // 获取该商品图片
        List<CommodityImage> commodityImages = commodityImageMapper.selectListByColumn(
            "commodity_uuid", commodity.getUuid());
        commodityVo.setImages(commodityImages.stream().map(CommodityImage::getImageUrl).collect(
            Collectors.toList()));
        return commodityVo;
    }

    /**
     * 删除商品
     *
     * @param commodityUuid
     */
    @Override
    public void delete(String commodityUuid) {
        commodityMapper.deleteById(commodityUuid);
    }

    /**
     * 下架
     *
     * @param uuid
     */
    @Override
    public void drop(String uuid) {
        Commodity commodity = commodityMapper.findById(uuid)
            .orElseThrow(() -> new BusinessException("商品不存在"));
        commodity.setStatus(CommodityStatus.OFF_SHELF);
        // 商品下架后自动从自由广场取消同步
        commodity.setIsSyncLibertySquare(false);
        commodityMapper.updateById(commodity);
    }

    /**
     * 上架
     *
     * @param uuid
     */
    @Override
    public void put(String uuid) {
        Commodity commodity = commodityMapper.findById(uuid)
            .orElseThrow(() -> new BusinessException("商品不存在"));
        // 判断是否被管理员下架
        if (commodity.getIsAdminOff()) {
            throw new BusinessException("商品已被管理员下架，请联系管理员");
        }
        commodity.setStatus(CommodityStatus.ON_SHELF);
        commodityMapper.updateById(commodity);
    }

    /**
     * 收藏商品
     *
     * @param uuid
     * @param currentLoginUuid
     */
    @Override
    public void collect(String uuid, String currentLoginUuid) {
        Commodity commodity = commodityMapper.findById(uuid)
            .orElseThrow(() -> new BusinessException("商品不存在"));
        if (commodity.getStatus().equals(CommodityStatus.OFF_SHELF)) {
            throw new BusinessException("商品已下架");
        }
        CommodityCollection commodityCollection = CommodityCollection.builder()
            .uuid(UUIDGenerator.getUUID())
            .commodityUuid(uuid)
            .collectUserUuid(currentLoginUuid)
            .build();
        commodityCollectionMapper.insert(commodityCollection);
    }

    /**
     * 是否收藏
     *
     * @param uuid
     * @param currentLoginUuid
     * @return
     */
    @Override
    public Boolean isCollect(String uuid, String currentLoginUuid) {
        return commodityCollectionMapper.isCollect(uuid, currentLoginUuid);
    }

    /**
     * 取消收藏
     *
     * @param uuid
     * @param currentLoginUuid
     * @return
     */
    @Override
    public void cancelCollect(String uuid, String currentLoginUuid) {
        commodityCollectionMapper.cancelCollect(uuid, currentLoginUuid);
    }

    /**
     * 修改商品
     *
     * @param commodityAddOrUpdateBo
     */
    @Override
    public void edit(CommodityAddOrUpdateBo commodityAddOrUpdateBo) {
        Commodity commodity = commodityMapper.findById(commodityAddOrUpdateBo.getUuid())
            .orElseThrow(() -> new BusinessException("商品不存在"));
        if (commodity.getStatus().equals(CommodityStatus.PENDING_REVIEW)) {
            throw new BusinessException("该商品处于待审核，不能修改");
        }
        if (commodity.getStatus().equals(CommodityStatus.ON_SHELF)) {
            throw new BusinessException("该商品已上架，不能修改");
        }
        if (commodity.getIsAdminOff()) {
            throw new BusinessException("该商品已被管理员下架，不能修改");
        }
        if (externalApiData.checkSensitiveWords(commodityAddOrUpdateBo.getTitle()) || externalApiData.checkSensitiveWords(commodityAddOrUpdateBo.getDescription())) {
            throw new BusinessException("商品标题或描述存在敏感词");
        }
        BeanUtil.copyProperties(commodityAddOrUpdateBo, commodity);
        commodity.setIsAdminOff(false);
        commodity.setStatus(CommodityStatus.PENDING_REVIEW);
        commodityMapper.updateById(commodity);
        // 保存图片信息
        // 1，先删除之前的图片
        commodityImageMapper.deleteByColumn("commodity_uuid", commodityAddOrUpdateBo.getUuid());
        // 2，保存新图片信息
        for (String imageUrl : commodityAddOrUpdateBo.getImageUrls()) {
            CommodityImage commodityImage = CommodityImage.builder()
                .imageUrl(imageUrl).commodityUuid(commodity.getUuid())
                .uuid(UUIDGenerator.getUUID()).build();
            commodityImageMapper.insert(commodityImage);
        }
    }

    /**
     * 同步自由广场
     *
     * @param uuid
     */
    @Override
    public void syncLibertySquare(String uuid) {
        Commodity commodity = commodityMapper.findById(uuid)
            .orElseThrow(() -> new BusinessException("商品不存在"));
        if (commodity.getStatus().equals(CommodityStatus.PENDING_REVIEW)) {
            throw new BusinessException("该商品处于待审核，不能同步");
        }
        if (commodity.getStatus().equals(CommodityStatus.OFF_SHELF)) {
            throw new BusinessException("该商品已下架，不能同步");
        }
        if (commodity.getIsAdminOff()) {
            throw new BusinessException("该商品已被管理员下架，不能同步");
        }
        commodity.setIsSyncLibertySquare(true);
        commodityMapper.updateById(commodity);
    }

    /**
     * 取消同步自由广场
     *
     * @param uuid
     */
    @Override
    public void cancelSyncLibertySquare(String uuid) {
        Commodity commodity = commodityMapper.findById(uuid)
            .orElseThrow(() -> new BusinessException("商品不存在"));
        if (commodity.getStatus().equals(CommodityStatus.PENDING_REVIEW)) {
            throw new BusinessException("该商品处于待审核，不能取消同步");
        }
        if (commodity.getStatus().equals(CommodityStatus.OFF_SHELF)) {
            throw new BusinessException("该商品已下架，不能取消同步");
        }
        if (commodity.getIsAdminOff()) {
            throw new BusinessException("该商品已被管理员下架，不能取消同步");
        }
        commodity.setIsSyncLibertySquare(false);
        commodityMapper.updateById(commodity);
    }
}
